#ifndef AGORA
#define AGORA

#include "IAudioIn.h"
#include "IAudioOut.h"
#include "IEmpacter.h"
#include "IEncoder.h"
#include "IMutex.h"
#include "Client2.h"
#include <map>
#include <list>


class Agora
{
public:
	Agora();
	~Agora();

	int Connect(std::string adress, int port);

	int		AddAudioInput(IAudioIn *audioIn, unsigned int frameSize);
	void	AddEncoder(IEncoder *encoder, char headerValue);
	void	RemoveEncoder(char headerValue);
	void	RemoveAudioInput(int audioInputKey);
	void	AddDefaultMicro(unsigned int freq, char format);

	void SetEncoderQuality(char headerValue, unsigned int quality);
	int CreateDefaultMicro(FrequenceEnum frequence, ALFormat format);
	void CreateDefaultEncoder(unsigned int quality, char headerValue);
	void CreateDefaultEmpacter();
	void CreateDefaultClient();
	void CreateDefaultAudioOut();

	void SetEncoderForAudioInput(char HeaderValue, int audioInputKey);
	void StartAudioInput(int audioInputKey);
	void StopAudioInput(int audioInputKey);

	void StartAudioInput();
	void StopAudioInput();
	void StartAudioOut();
	void StopAudioOut();

	void SetLocalTest(bool state);
	bool GetLocalTest();

// DEBUG BETA2 = bouger dans stat:
	unsigned int GetUploadRate();
	unsigned int GetDownloadRate();
// END DEBUG

	bool	IsConnected();
	void	Disconnect();

private:
	struct AudioInInfo
	{
		IAudioIn	*audioIn;
		IBuffer		*bufferIn;
		IBuffer		*bufferEncoded;
		IBuffer		*bufferEmpacked;
		char		encoderKey;
	};
	struct EncoderInfo
	{
		IEncoder* encoder;
		IMutex*	  mutex;
	};

	static void EncodeBuffer(IBuffer* buff, void* data);
	static void SendBuffer(IBuffer*, void*);
	static void ReceiveDataFromClient(IBuffer*, void*);
	static void EmpackedBuffer(IBuffer* buff, void* data);

// DEBUG :
	unsigned int _upload;
	unsigned int _download;
	unsigned int _uploadPerSec;
	unsigned int _downloadPerSec;
    bool _checkBandwidth;
	bool	_localTest;
	static void UpdateBandwidth(void* data);
// END DEBUG

	IBuffer			*_bufReception;
	std::map<int, IBuffer *> _bufSources;
	
	IAudioOut *_audioOut;
	IEmpacter *_empacter;

	std::map<char, EncoderInfo*> _encoders;


	std::map<IBuffer *, AudioInInfo *> _audioInfoFromIn;
	std::map<IBuffer *, AudioInInfo *> _audioInfoFromEncoded;
	std::map<IBuffer *, AudioInInfo *> _audioInfoFromEmpacked;
	std::list<AudioInInfo*> _audioIns;

	Client	  *_client;
};



#endif